package com.iretailer.report.quartz.horizon.visitors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.iretailer.report.model.*;
import com.iretailer.report.quartz.horizon.Settings;
import com.iretailer.report.quartz.horizon.common.ClientHttpMethod;
import com.iretailer.report.quartz.horizon.common.Signer;
import com.iretailer.report.quartz.horizon.model.Pagination;
import com.iretailer.report.quartz.horizon.model.VisitorsBody;
import com.iretailer.report.quartz.horizon.model.VisitorsRecords;
import com.iretailer.report.service.BusinessTimeService;
import com.iretailer.report.service.CategoriesService;
import com.iretailer.report.service.DevicesService;
import com.iretailer.report.service.FaceService;
import com.iretailer.report.util.StringUtil;
import com.iretailer.report.util.TimeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.time.*;
import java.util.*;

/**
 * @Auther: xjw
 * @Date: 2019/10/22 0022 16:20
 * @Description:
 */
@Component
public class GetVisitors {
    private final static Logger log = LoggerFactory.getLogger(GetVisitors.class);
    @Autowired
    private FaceService faceService;
    @Autowired
    private DevicesService devicesService;
    @Autowired
    private BusinessTimeService businessTimeService;
    @Autowired
    private CategoriesService categoriesService;

    public void execute() {
        LocalDate localDate = LocalDate.now();
        executeHistory(localDate);
    }

    public void executeHistory(LocalDate localDate) {
        Signer signer = new Signer(Settings.AK, Settings.SK);
        Categories face = categoriesService.selectCategoryByKeyName("FaceDevice");
        List<Device> devices = devicesService.list(new QueryWrapper<Device>().lambda().eq(Device::getDeviceType, face.getId()));
        Map<String, Categories> ageTypeMap = categoriesService.getAgeTypeMap();
        for (Device d : devices) {
            if (StringUtil.notEmpty(d.getSerialNumber())) {
                MallBusinessTime mallBusinessTime = businessTimeService.filterBusinessTime(d.getMallId(), LocalDateTime.now());
                if (StringUtil.notEmpty(mallBusinessTime.getTimeZone())) {
                    ZoneId zoneId = ZoneId.of(mallBusinessTime.getTimeZone());
                    ZonedDateTime start = ZonedDateTime.of(localDate, TimeUtil.parse_LocalTime(mallBusinessTime.getStartTime()), zoneId);
                    ZonedDateTime end = ZonedDateTime.of(localDate, TimeUtil.parse_LocalTime(mallBusinessTime.getEndTime()), zoneId);
                    allData(signer, 1, 100, d, start, end, zoneId, ageTypeMap);
                } else {
                    log.error("---- visitors mall business is empty");
                }
            }
        }
    }

    public void allData(Signer signer, int current, int perPage, Device d, ZonedDateTime start, ZonedDateTime end, ZoneId zoneId, Map<String, Categories> ageTypeMap) {
        VisitorsBody body = deviceVisitors(signer, current, perPage, d.getSerialNumber(), start.toLocalDateTime(), end.toLocalDateTime(), start.getOffset());
        if (body != null && body.getData().getRecords().size() > 0) {
            List<GenderAge> genderAges = new ArrayList<>();
            for (VisitorsRecords r : body.getData().getRecords()) {
                genderAges.add(record2GenderAge(r, d.getId(), zoneId, ageTypeMap));
            }
            faceService.replaceGenderAges(genderAges);
            Pagination page = body.getPagination();

            int allPage = page.getTotal() % page.getPer_page() > 0 ? page.getTotal() / page.getPer_page() + 1 : page.getTotal() / page.getPer_page();
            if (allPage > current) {
                allData(signer, current + 1, perPage, d, start, end, zoneId, ageTypeMap);
            }
        }

    }

    /**
     * 到店记录查询
     * // 设备号查询
     *
     * @return
     */
    public VisitorsBody deviceVisitors(Signer signer, int current, int perPage, String deviceSn, LocalDateTime startTime, LocalDateTime endTime, ZoneOffset offset) {
        String APIURL = String.format("/openapi/v1/analysis_tools/%s/visitors", deviceSn);
        SortedMap<String, String> params = new TreeMap<>();
        SortedMap<String, String> headers = new TreeMap<String, String>();
        headers.put("host", Settings.PAAS_HOST);
        params.put("current", String.valueOf(current));
        params.put("per_page", String.valueOf(perPage));
        params.put("start_time", TimeUtil.getISODateTime(startTime, offset));
        params.put("end_time", TimeUtil.getISODateTime(endTime, offset));
        try {
            ResponseEntity<VisitorsBody> result = ClientHttpMethod.getHttpMethod(signer).httpGet(VisitorsBody.class, APIURL, headers, params);
            if (result.getStatusCodeValue() == HttpStatus.OK.value()) {
                VisitorsBody body = result.getBody();
//                log.error(JSON.toJSONString(body));
                if (body.getMessage().equals("success")) {
                    return body;
                } else {
                    log.error("---- get visitors is error {} ", JSONObject.toJSON(body));
                }
            } else {
                log.error("---- get visitors is error StartusCode: {}", result.getStatusCodeValue());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    public GenderAge record2GenderAge(VisitorsRecords r, long did, ZoneId zoneId, Map<String, Categories> ageTypeMap) {
        GenderAge genderAge = new GenderAge();
        Categories ageType = ageTypeMap.get(String.valueOf(r.getAge()));
        if (ageType != null) {
            genderAge.setAgeType(ageType.getData());
        } else {
            genderAge.setAgeType("");
        }
        genderAge.setGender(r.getGender());
        LocalDateTime localDateTime = r.getCapture_time().withZoneSameInstant(zoneId).toLocalDateTime();
        genderAge.setDate(localDateTime.toLocalDate());
        genderAge.setDateTime(localDateTime);
        genderAge.setDid(did);
        genderAge.setPersonId(r.getFace_id());
        genderAge.setImageUrl(r.getCapture_url().getString("url"));
        return genderAge;
    }


}
